/**
 * 
 */
package platzerworld.kegeln.db;

import platzerworld.kegeln.db.ergebnis.ErgebnisTbl;
import platzerworld.kegeln.db.klasse.KlasseTbl;
import platzerworld.kegeln.db.klasse.KlassenGenerator;
import platzerworld.kegeln.db.mannschaft.MannschaftTbl;
import platzerworld.kegeln.db.spieler.SpielerTbl;
import platzerworld.kegeln.db.verein.VereinTbl;
import platzerworld.kegeln.db.wettkampf.WettkampfTbl;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteStatement;
import android.util.Log;

/**
 * Die Klasse dient als logische Verbindung zur Datenbank der Anwendung. Sie ist f�r die Erstellung und Wartung des Datenbankschemas
 * sowie die Initialbef�llung der Tabellen verantwortlich.
 * Die Datenbank 'KegelverwaltungDatenbank' wird unter /sdcard/kegeln/kegelverwaltung.db gespeichert.
 * 
 * Die Klassen KegelverwaltungGAEDatenbank und KegelverwaltungCSVDatenbank erweitern die Klasse f�r GAE und CSV Import.
 * 
 * @author platzerg
 */
public class KegelverwaltungDatenbank extends SQLiteOpenHelper {

	/** Markierung f�r Logging. */
	private static final String TAG = "KegelverwaltungDatenbank";

	/** Name der Datenbankdatei. */
	protected static final String DATENBANK_NAME = "/sdcard/kegeln/kegelverwaltung.db";

	protected static SQLiteDatabase db;
	protected final Context mContext;
	
	/**
	 * Version des Schemas.
	 */
	protected static final int DATENBANK_VERSION = 1;

	/**
	 * Die Datenbank kann nur nach Kenntnis "ihrer" Anwendung verwaltet werden.
	 * Daher muss der Context der Anwendung �bergeben werden.
	 * 
	 * @param context Context der aufrufenden Anwendung.
	 */
	public KegelverwaltungDatenbank(Context context) {
		super(context, DATENBANK_NAME, null, DATENBANK_VERSION);
		mContext = context;
	}
	
	/**
	 * Wird aufgerufen, wenn das Datenbankschema neu angelegt werden soll. Die Tabellen werden angelegt.
	 * Anschlie�end wird die Initialbef�llung der Datenbank durchgef�hrt.
	 * 
	 * @param db aktuelle Datenbank-Verbindung
	 */
	@Override
	public void onCreate(SQLiteDatabase db) {
		KegelverwaltungDatenbank.db = db;
		initDatabase(mContext);
	}
	
	/**
	 * L�schen und Erzeugung der Tabellen, sowie Initialbef�llung.
	 */
	public void resetDB(){
		SQLiteDatabase dbCon = null;
		try{
		 dbCon = getWritableDatabase();
			if(null != dbCon){
				dbCon.execSQL(ErgebnisTbl.SQL_DROP);
				dbCon.execSQL(SpielerTbl.SQL_DROP);
				dbCon.execSQL(MannschaftTbl.SQL_DROP);
				dbCon.execSQL(VereinTbl.SQL_DROP);
				dbCon.execSQL(KlasseTbl.SQL_DROP);
				dbCon.execSQL(WettkampfTbl.SQL_DROP);
				
				dbCon.close();
				
				KegelverwaltungDatenbank.db = getWritableDatabase();
				initDatabase(mContext);
			}
		} finally {
			dbCon.close();
			if(KegelverwaltungDatenbank.db.isOpen()){
				KegelverwaltungDatenbank.db.close();
			}
		}
	}
	
	/**
	 * L�schen der Tabellen.
	 */
	public void deleteTable(){
		SQLiteDatabase dbCon = null;
		try{
		 dbCon = getWritableDatabase();
			if(null != dbCon){
				dbCon.execSQL(ErgebnisTbl.SQL_DROP);
				dbCon.execSQL(SpielerTbl.SQL_DROP);
				dbCon.execSQL(MannschaftTbl.SQL_DROP);
				dbCon.execSQL(VereinTbl.SQL_DROP);
				dbCon.execSQL(KlasseTbl.SQL_DROP);
				dbCon.execSQL(WettkampfTbl.SQL_DROP);
				
				dbCon.close();
			}
		} finally {
			dbCon.close();
		}
	}
	
	/**
	 * Erzeugung der Tabellen.
	 */
	public void createTable(){
		SQLiteDatabase dbCon = null;
		try{
		 dbCon = getWritableDatabase();
			if(null != dbCon){
				dbCon.execSQL(KlasseTbl.SQL_CREATE);
				dbCon.execSQL(VereinTbl.SQL_CREATE);
				dbCon.execSQL(MannschaftTbl.SQL_CREATE);
				dbCon.execSQL(SpielerTbl.SQL_CREATE);
				dbCon.execSQL(ErgebnisTbl.SQL_CREATE);
				dbCon.execSQL(WettkampfTbl.SQL_CREATE);
				
				dbCon.close();
			}
		} finally {
			dbCon.close();
		}
	}
	
	/**
	 * L�schen der Datens�tze aus den Tabellen.
	 */
	public void deleteData(){
		SQLiteDatabase dbCon = null;
		try{
		 dbCon = getWritableDatabase();
			if(null != dbCon){
				dbCon.execSQL(ErgebnisTbl.STMT_DELETE);
				dbCon.execSQL(SpielerTbl.STMT_SPIELER_DELETE);
				dbCon.execSQL(MannschaftTbl.STMT_MANNSCHAFT_DELETE);
				dbCon.execSQL(VereinTbl.STMT_VEREIN_DELETE);
				dbCon.execSQL(KlasseTbl.STMT_KLASSE_DELETE);
				dbCon.execSQL(WettkampfTbl.STMT_WETTKAMPF_DELETE);
				
				dbCon.close();
			}
		} finally {
			dbCon.close();
		}
	}
	
	/**
	 * Auf die Tabell sqlite_sequence ein reset durchf�hren.
	 */
	public void resetAutoincrements(){
		try{
			 db = getWritableDatabase();
				if(null != db){
					try {
						db.beginTransaction();
						
						final SQLiteStatement stmtResetKLasse = db.compileStatement("delete from sqlite_sequence;");						
						stmtResetKLasse.execute();
						db.setTransactionSuccessful();
					} catch (Throwable ex) {
						Log.e(TAG, "Fehler beim Reset des Autoincrements. " + ex);
					} finally {
						db.endTransaction();
					}

				}
			} finally {
				db.close();
			}
	}
	
	/**
	 * Einf�gen der Datens�tze.
	 */
	public void insertData(){
		try{
		 db = getWritableDatabase();
			if(null != db){
				erzeugeKlassenDaten(db, mContext, false);
				erzeugeVereinDaten(db, false);
				erzeugeMannschaftDaten(db, false);
				erzeugeSpielerDaten(db, false);
				erzeugeErgebnisDaten(db, false);
				erzeugeWettkampfDaten(db, false);
			}
		} finally {
			db.close();
		}
	}

	/**
	 * Erzeugen der Tabellen und Initialbef�llung, wobei bestehende Datens�tze gel�scht werden.
	 * 
	 * @param mContext Context der aufrufenden Anwendung.
	 */
	public void initDatabase(Context mContext) {
		db.execSQL(KlasseTbl.SQL_CREATE);
		db.execSQL(VereinTbl.SQL_CREATE);
		db.execSQL(MannschaftTbl.SQL_CREATE);
		db.execSQL(SpielerTbl.SQL_CREATE);
		db.execSQL(ErgebnisTbl.SQL_CREATE);
		db.execSQL(WettkampfTbl.SQL_CREATE);

		
		erzeugeKlassenDaten(db, mContext, true);
		erzeugeVereinDaten(db, true);
		erzeugeMannschaftDaten(db, true);
		erzeugeSpielerDaten(db, true);
		erzeugeErgebnisDaten(db, true);
		erzeugeWettkampfDaten(db, true);
		
	}

	/**
	 * Wird aufgerufen, wenn sich die Version des Schemas ge�ndert hat. In diesem Fall wird die 
	 * Datenbank gel�scht und mit neuem Schema wieder aufgebaut.
	 * 
	 * 
	 * @param db aktuelle Datenbank-Verbindung
	 * @param oldVersion bisherige Schemaversion
	 * @param newVersion neue Schemaversion
	 */
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion
				+ ", which will destroy all old data");
		db.execSQL(KlasseTbl.SQL_DROP);
		onCreate(db);
	}

	/**
	 * Hier werden die Stammdaten f�r die Spielklassen erzeugt.
	 * 
	 * @param db aktuelle Datenbank-Verbindung.
	 * @param mContext Context der aufrufenden Anwendung.
	 * @param deleteOldData true dann werden bestehende Daten gel�scht
	 * 
	 */
	private static void erzeugeKlassenDaten(SQLiteDatabase db, Context mContext, boolean deleteOldData) {
		// loesche vorhandene daten
		if(deleteOldData){
			db.delete(KlasseTbl.TABLE_NAME, null, null);
		}

		final SQLiteStatement stmtInsertKlasse = db.compileStatement(KlasseTbl.STMT_KLASSE_INSERT);

		String[] klassen = {"Klasse1", "Klasse2", "Klasse3"};
		db.beginTransaction();

		try {
			for (int r = 0; r < klassen.length; r++) {
				stmtInsertKlasse.bindString(1, "KW");
				stmtInsertKlasse.bindString(2, klassen[r]);
				stmtInsertKlasse.bindString(3, "");
				stmtInsertKlasse.executeInsert();
			}
			db.setTransactionSuccessful();
		} catch (Throwable ex) {
			Log.e(TAG, "Fehler beim Einf�gen eines Klassen-Testdatensatzes. " + ex);
		} finally {
			db.endTransaction();
		}
	}

	/**
	 * Hier werden die Stammdaten f�r die Mannschaften erzeugt.
	 * 
	 * @param db aktuelle Datenbank-Verbindung.
	 * @param deleteOldData true dann werden bestehende Daten gel�scht
	 * 
	 */
	private static void erzeugeMannschaftDaten(SQLiteDatabase db, boolean deleteOldData) {
		// loesche vorhandene daten
		if(deleteOldData){
			db.delete(MannschaftTbl.TABLE_NAME, null, null);
		}

		final SQLiteStatement stmtInsertMannschaft = db.compileStatement(MannschaftTbl.STMT_NAME_KLASSE_MANNSCHAFT_INSERT);

		db.beginTransaction();

		try {
			KlassenGenerator.erzeugeBezirksoberliga(stmtInsertMannschaft);
			KlassenGenerator.erzeugeBezirksliga(stmtInsertMannschaft);
			KlassenGenerator.erzeugeBezirksklasse(stmtInsertMannschaft);
			KlassenGenerator.erzeugeKreisliga(stmtInsertMannschaft);
			KlassenGenerator.erzeugeKreisklasse(stmtInsertMannschaft);
			KlassenGenerator.erzeugeAKlasse(stmtInsertMannschaft);
			KlassenGenerator.erzeugeBKlasse(stmtInsertMannschaft);
			KlassenGenerator.erzeugeCKlasse(stmtInsertMannschaft);

			db.setTransactionSuccessful();
		} catch (Throwable ex) {
			Log.e(TAG, "Fehler beim Einf�gen eines Mannschaft-Testdatensatzes. " + ex);
		} finally {
			db.endTransaction();
		}
	}

	/**
	 * Hier werden die Stammdaten f�r die Spieler erzeugt.
	 * 
	 * @param db aktuelle Datenbank-Verbindung.
	 * @param deleteOldData true dann werden bestehende Daten gel�scht
	 * 
	 */
	private static void erzeugeSpielerDaten(SQLiteDatabase db, boolean deleteOldData) {
		// loesche vorhandene daten
		if(deleteOldData){
			db.delete(SpielerTbl.TABLE_NAME, null, null);
		}

		final SQLiteStatement stmtInsertSpieler = db.compileStatement(SpielerTbl.STMT_ALL_INSERT);

		db.beginTransaction();

		try {
			stmtInsertSpieler.bindLong(1, 53);
			stmtInsertSpieler.bindLong(2, 0);
			stmtInsertSpieler.bindLong(3, 123);
			stmtInsertSpieler.bindString(4, "Platzer");
			stmtInsertSpieler.bindString(5, "G�nter");
			stmtInsertSpieler.bindString(6, "13.04.1972");
			stmtInsertSpieler.bindLong(7, (int) (48.17968 * 1E6));
			stmtInsertSpieler.bindLong(8, (int) (11.5922 * 1E6));
			stmtInsertSpieler.executeInsert();
			
			stmtInsertSpieler.bindLong(1, 53);
			stmtInsertSpieler.bindLong(2, 0);
			stmtInsertSpieler.bindLong(3, 456);
			stmtInsertSpieler.bindString(4, "Arras");
			stmtInsertSpieler.bindString(5, "Klaus");
			stmtInsertSpieler.bindString(6, "12.09.1960");
			stmtInsertSpieler.bindLong(7, (int) (48.17968 * 1E6));
			stmtInsertSpieler.bindLong(8, (int) (11.5922 * 1E6));
			stmtInsertSpieler.executeInsert();
			
			db.setTransactionSuccessful();
		} catch (Throwable ex) {
			Log.e(TAG, "Fehler beim Einf�gen eines Spieler-Testdatensatzes. " + ex);
		} finally {
			db.endTransaction();
		}
	}

	/**
	 * Hier werden die Stammdaten f�r die Vereine erzeugt.
	 * 
	 * @param db aktuelle Datenbank-Verbindung.
	 * @param deleteOldData true dann werden bestehende Daten gel�scht
	 * 
	 */
	private static void erzeugeVereinDaten(SQLiteDatabase db,boolean deleteOldData) {
		// loesche vorhandene daten
		if(deleteOldData){
			db.delete(VereinTbl.TABLE_NAME, null, null);
		}

		final SQLiteStatement stmtInsertVerein = db.compileStatement(VereinTbl.STMT_VEREIN_INSERT);

		db.beginTransaction();

		try {
			stmtInsertVerein.bindString(1, "KC-Ismaning");
			stmtInsertVerein.bindLong(2, 11);
			stmtInsertVerein.bindString(3, "KC Ism");
			stmtInsertVerein.executeInsert();
			
			stmtInsertVerein.bindString(1, "SG Mosinning");
			stmtInsertVerein.bindLong(2, 10);
			stmtInsertVerein.bindString(3, "SG Mos");
			stmtInsertVerein.executeInsert();

			db.setTransactionSuccessful();
		} catch (Throwable ex) {
			Log.e(TAG, "Fehler beim Einf�gen eines Verein-Testdatensatzes. " + ex);
		} finally {
			db.endTransaction();
		}
	}
	
	/**
	 * Hier werden die Stammdaten f�r die Ergebnisse erzeugt.
	 * 
	 * @param db aktuelle Datenbank-Verbindung.
	 * @param deleteOldData true dann werden bestehende Daten gel�scht
	 * 
	 */
	private static void erzeugeErgebnisDaten(SQLiteDatabase db, boolean deleteOldData) {
		// loesche vorhandene daten
		if(deleteOldData){
			db.delete(ErgebnisTbl.TABLE_NAME, null, null);
		}

		final SQLiteStatement stmtInsertErgebnis = db.compileStatement(ErgebnisTbl.STMT_MAX_INSERT);

		db.beginTransaction();

		try {
			//KlassenGenerator.erzeugeBezirksoberliga(stmtInsertKontakt);
			stmtInsertErgebnis.bindLong(1, 1);
			stmtInsertErgebnis.bindLong(2, 1);
			stmtInsertErgebnis.bindLong(3, 1);
			stmtInsertErgebnis.bindLong(4, 457);
			
			stmtInsertErgebnis.bindLong(5, 230);
			stmtInsertErgebnis.bindLong(6, 227);
			
			stmtInsertErgebnis.bindLong(7, 160);
			stmtInsertErgebnis.bindLong(8, 150);
			
			stmtInsertErgebnis.bindLong(9, 70);
			stmtInsertErgebnis.bindLong(10, 77);
			
			stmtInsertErgebnis.bindLong(11, 1);
			stmtInsertErgebnis.bindLong(12, 0);
			
			stmtInsertErgebnis.executeInsert();

			db.setTransactionSuccessful();
		} catch (Throwable ex) {
			Log.e(TAG, "Fehler beim Einf�gen eines Testdatensatzes. " + ex);
		} finally {
			db.endTransaction();
		}
	}
	
	/**
	 * Hier werden die Stammdaten f�r die Wettk�mpfe erzeugt.
	 * 
	 * @param db aktuelle Datenbank-Verbindung.
	 * @param deleteOldData true dann werden bestehende Daten gel�scht
	 * 
	 */
	private static void erzeugeWettkampfDaten(SQLiteDatabase db, boolean deleteOldData) {
		// loesche vorhandene daten
		if(deleteOldData){
			db.delete(WettkampfTbl.TABLE_NAME, null, null);
		}

		final SQLiteStatement stmtInsertWettkampf = db.compileStatement(WettkampfTbl.STMT_MAX_INSERT);

		db.beginTransaction();
		// spiel_nr, heim_id, gast_id, klasse_id, spiel_zeit
		try {
			stmtInsertWettkampf.bindLong(1, 1);
			stmtInsertWettkampf.bindLong(2, 10);
			stmtInsertWettkampf.bindLong(3, 11);
			stmtInsertWettkampf.bindLong(4, 1);
			stmtInsertWettkampf.bindString(5, "20.01.2011 12:34");
			
			stmtInsertWettkampf.bindString(6, "-");
			stmtInsertWettkampf.bindLong(7, 11);
			stmtInsertWettkampf.bindLong(8, 11);
			
			stmtInsertWettkampf.bindString(9, "-");
			stmtInsertWettkampf.bindLong(10, 11);
			stmtInsertWettkampf.bindLong(11, 11);
			
			stmtInsertWettkampf.bindString(12, "-");
			stmtInsertWettkampf.bindLong(13, 11);
			stmtInsertWettkampf.bindLong(14, 11);
			
			stmtInsertWettkampf.bindString(15, "-");
			stmtInsertWettkampf.bindLong(16, 11);
			stmtInsertWettkampf.bindLong(17, 11);
			
			stmtInsertWettkampf.bindString(18, "-");
			stmtInsertWettkampf.bindLong(19, 11);
			stmtInsertWettkampf.bindLong(20, 11);
			
			stmtInsertWettkampf.bindString(21, "2019-1989");
			
			stmtInsertWettkampf.executeInsert();
			
			db.setTransactionSuccessful();
		} catch (Throwable ex) {
			Log.e(TAG, "Fehler beim Einf�gen eines Testdatensatzes. " + ex);
		} finally {
			db.endTransaction();
		}
	}
}
